テスト駆動開発 指針
#テスト駆動開発 #TDD
テスト駆動開発の良さみたいなのは、記事を読む限りなんとなくフワッとわかるんだが...
自分でテスト駆動開発できるか?と言われるとできない。つまり、まだ自分のものになってはいない。
なので、自分で実際に手を動かし、テスト駆動開発のポイントやら良し悪しやらを自分の頭で理解して、自分の指針を作る。
目次
指針
テスト戦略
1週間ほどテスト駆動開発をやってみての感想
参考
指針
hr.icon
以下の流れに沿ってTDDを実践していく(基本は「(Design ->) Red -> Green -> Refactoring」のサイクル)
1. テスト対象にする部品の詳細設計・使い方を決める
ここが一番重要だと思ってる。ここを曖昧な感じのままにして進めちゃうと、絶対に手戻りが起きる。
TDDで書いてる分、手戻りコストが増える...。だから、そうならないよう、最初の詳細設計はしっかりやる。
よくFizzBuzzを返す関数のTDDとかお題であるが、これは詳細設計が簡単すぎる。関数を作ればいいだけだもの。
実務だと、もう少し難しい部品作成になるはず。まず、クラスか関数のどちらで実装しよう?的な話になりそうだし、サブ部品が必要か?必要ならどういう部品になる?みたいな話も出てきそう。その他諸々出てくるはず(名付けとか)
そういう詳細設計をちゃんとした上で、TDDに入っていくのが良いと思う。
2. 「1.」で作った詳細設計・使い方などを基にTodoリスト(= ほぼテストケースになりそう)を作る
サブ部品とか出てきたなら、それも加味した構造化されたTodoリストを作ること
3. 複数部品があるなら依存ツリーの一番下(依存されてない側)の部品からTDDに入っていく
4. Todoを1つ選んで、テストコードを作成して失敗させる(RED)
5. テストコードが成功するプロダクションコードを作成して成功させる(Green)
この時、プロダクションコードに書くコードは、マジで適当でもいい。return '1'とかでもいい。
とにかく、テストコードがGreenになるようにしろ。
理由:テストコードのテストをするため。
テストコードを成功させようとしたのに、失敗するなら、おそらくテストコードに問題がある。
この工程を侮るなかれ、意外と有用だぜ。
6. テストコードがGreenになるままで、プロダクションコードをリファクタリングする(Refactoring)
7. 4 ~ 6を繰り返す
テスト戦略
hr.icon
TDDをより早く正確に使いこなすためには「テストケースの上手い作り方」や「テストコードの慣れ」が必要。
この節では、テストケースを上手く作るための戦略についてまとめる。
1週間ほどテスト駆動開発をやってみての感想
hr.icon
以下のブログにある題材を参考に、1週間ほどテスト駆動開発を意識してやってみた。その時の感想を徒然に綴る。
テスト駆動開発の題材を目的別で紹介する - ブロッコリーのブログ
「ー」寄りの感想
テストコードの書き方に慣れてないと、TDDは挫折するかも
自分はpython使いであり、テストにpytestを使う。
指針は既に作ってるので、TDDにおけるこの障壁を超えることは自分は可能ではある。
ただ、昔の自分の状態(pytestに慣れてない状態)で、TDDを始めてたら、絶対にTDDなんてできなかったと思う。
モックの書き方とか知らないと、絶対にTDD途中で乙る。
「TDDを始める前にその言語のテストコードの書き方に慣れておかないと挫折するだろう」と思った。
実際、自分ははるか昔にTDDに挑戦したが、テストコードに慣れてなくて挫折した気がする。
テストケースの作り方を知ってないと、TDDは挫折するかも
正常系、異常系から始まり、ホワイト/ブラックボックス、境界の考え方、カバレッジなどなど。
その機能のテストをできるだけ網羅できるようにする必要がある。そこには正常系/異常系で分けたり、境界値的な考え方が必要だったりする。
できるだけ網羅ってどれくらいやねん?(網羅率)みたいな考え方も心得ておく必要がある。
こういう知識に対する理解をすることで、いい感じのテストケースを作ることができる。
自分は、少し完璧主義なところがあるので、TDDどころではなく、どうやっていい感じのテストケース作るんだ?って思考になっちまった。足りてるかな?怖いなって。
設計が途中で変わったら、テストコード総入れ替えになっちまわねぇか?
例えば、テストコードを書いた後、プロダクションコードを書いた後に「あ、、こういう設計の方がいいかも」ってなる可能性あり。(実際になった)
こうなってしまった場合、テストコードを書いた時間が無駄にならねぇか?
それなら先にプロダクションコードから書いて、色んな設計の試行を経た上でテストコード書いた方がいいのでは?
こんなことを考えてしまった。
それは、、、テストコードを書く前に、その関数、クラスなどの使い方を先に思考してないからだという反論もありそう。
確かにそう。テストケースを作ってる時に、そこら辺は熟慮しておけってことよな。
ただ、コード書いてる途中に思いつくこともない?ないか。
設計・保守性高いコード設計の経験値や実力がある程度ないと、TDDはしんどいのではないか?
1つ上の感想に通ずることなんだけど、経験値高い人はコード書く前に頭の中で設計してさ、その上でテストケース・コードを作っていくんだろうと思う。
でも、経験足りない人だと、実際に書いてみないとわかんねぇ。
コード書かずに紙・頭の上だけで設計できねぇんだ。
だから思う、TDDする前に「保守性の高い設計・コード」を作る経験が必要なんじゃねぇか?と。
以上に記載したような経験値が足りないと、めっちゃ時間かかるはず
経験値が足りない場合、コードや設計を行ったり来たりして、めっちゃ時間かかると思う。
TDDは初心者にはしんどいんじゃねぇか?って思う。
中級者・上級者用の考え方なんじゃないかって思いました。
「+」寄りの感想
バチッとハマった時の安心感が半端ねぇ
必要なテストコードが動いてる保証があるので、書いたプロダクションコードに対する安心感が半端ない。
テストコードがOKてことは、仕様通りに動いてると保証されてるので、安心感が半端ない。
慣れてきたら普通よりも開発速度が速くなるだろう
「ー」の感想で、TDD以外の他の経験も必要だと記載した。
ただ、この経験があった上で、どんどんTDDを実施して行って実力を上げていけば、めちゃくちゃ生産性上がると思う。
「このコードはテストが全部通ってるから、一旦OKだ。次に行こう」みたいな考え方ができるようになる。
もしテストが無いと、不安になりながら進む事になるし、バグが発生しやすくなり、その修正に時間がかかることになる。
参考
hr.icon
TDD Boot Camp 2020 Online #1 基調講演/ライブコーディング
マージでわかりやすい。もうこれだけ見ておけばOK。